package com.bbm.bbmanage.service.impl;


import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bbm.bbmanage.entity.AppHttpCodeEnum;
import com.bbm.bbmanage.entity.House;
import com.bbm.bbmanage.entity.HouseProperty;
import com.bbm.bbmanage.entity.User;
import com.bbm.bbmanage.entity.dto.HouseDTO;
import com.bbm.bbmanage.entity.vo.HouseVo;
import com.bbm.bbmanage.entity.vo.PageVo;
import com.bbm.bbmanage.entity.vo.ResponseResult;
import com.bbm.bbmanage.mapper.HouseMapper;
import com.bbm.bbmanage.service.HouseImgService;
import com.bbm.bbmanage.service.HousePropertyService;
import com.bbm.bbmanage.service.HouseService;
import com.bbm.bbmanage.service.UserService;
import com.bbm.bbmanage.util.BeanCopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * (House)表服务实现类
 *
 * @author lionkliu
 * @since 2023-12-06 10:28:22
 */
@Service("houseService")
public class HouseServiceImpl extends ServiceImpl<HouseMapper, House> implements HouseService {
    @Autowired
    private UserService userService;

    @Resource
    private HouseImgService houseImgService;

    @Resource
    private HousePropertyService housePropertyService;


    @Override
    public ResponseResult selectPage(Integer pageNum, Integer pageSize) {
        return ResponseResult.okResult(page(new Page<>(pageNum, pageSize)));
    }

    @Override
    public ResponseResult selectOne(Long id) {
        return ResponseResult.okResult(getById(id));
    }

    @Override
    public ResponseResult insertOne(House house) {
        return save(house) ? ResponseResult.okResult() : ResponseResult.errorResult(AppHttpCodeEnum.INSERT_ERROR);
    }

    @Override
    public ResponseResult deleteById(Long id) {
        return removeById(id) ? ResponseResult.okResult() : ResponseResult.errorResult(AppHttpCodeEnum.DELETE_ERROR);
    }

    @Override
    public ResponseResult updateOne(House house) {
        LambdaUpdateWrapper<House> updateWrapper = new LambdaUpdateWrapper();
        updateWrapper.eq(House::getId, house.getId());
        if (house.getTitle() != null) {
            updateWrapper.set(House::getTitle, house.getTitle());
        }
        if (house.getDes() != null) {
            updateWrapper.set(House::getDes, house.getDes());
        }
        if (house.getImg() != null) {
            updateWrapper.set(House::getImg, house.getImg());
        }
        if (house.getAddress() != null) {
            updateWrapper.set(House::getAddress, house.getAddress());
        }
        if (house.getCategoryId() != null) {
            updateWrapper.set(House::getCategoryId, house.getCategoryId());
        }
        if (house.getPrice() != null) {
            updateWrapper.set(House::getPrice, house.getPrice());
        }
        if (house.getRest() != null) {
            updateWrapper.set(House::getRest, house.getRest());
        }
        return update(null, updateWrapper) ? ResponseResult.okResult() : ResponseResult.errorResult(AppHttpCodeEnum.UPDATE_ERROR);
    }

    @Override
    public ResponseResult getHousePage(Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<House> queryWrapper = new LambdaQueryWrapper<>();
        Page<House> page = new Page<>(pageNum, pageSize);
        Page<House> housePage = page(page, queryWrapper);
        PageVo<House> pageVo = new PageVo<>();
        pageVo.setResult(housePage.getRecords());
        pageVo.setTotal(housePage.getTotal());
        pageVo.setPageTotal(pageVo.getPageTotal(pageSize));
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult getByCategoryId(Long id) {
        LambdaQueryWrapper<House> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(House::getCategoryId, id);
        return ResponseResult.okResult(list(queryWrapper));
    }

    @Override
    public ResponseResult getByHouseId(Long id) {
        LambdaQueryWrapper<House> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(House::getId, id);
        House house = getOne(queryWrapper);
        HouseVo houseVo = BeanCopyUtils.copyBean(house, HouseVo.class);
        User user = userService.getById(house.getUserId());
        houseVo.setUsername(user.getUsername());
        houseVo.setAvatar(user.getAvatar());
        houseVo.setNickName(user.getNickName());
        return ResponseResult.okResult(houseVo);
    }

    @Override
    public ResponseResult searchByTitle(String title, Integer price, Integer stars) {
        LambdaQueryWrapper<House> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(House::getTitle, title);
        if (!Objects.isNull(price)) {
            if (price == 1) {
                queryWrapper.gt(House::getPrice, 200);
            } else if (price == 2) {
                queryWrapper.gt(House::getPrice, 100)
                        .ge(House::getPrice, 200);
            } else if (price == 3) {
                queryWrapper.le(House::getPrice, 100);
            }
        }
        if (!Objects.isNull(stars)) {
            if (stars == 1) {
                queryWrapper.ge(House::getStars, 4.8);
            } else if (stars == 2) {
                queryWrapper.ge(House::getStars, 4.5);
            } else if (stars == 3) {
                queryWrapper.ge(House::getStars, 4.2);
            }
        }
        List<House> houseList = list(queryWrapper);
        return ResponseResult.okResult(houseList);
    }

    @Override
    public ResponseResult search(Integer pageNum, Integer pageSize, String title, String address) {
        LambdaQueryWrapper<House> queryWrapper = new LambdaQueryWrapper<>();
        if (!Objects.isNull(title)) {
            queryWrapper.like(House::getTitle, title);
        }
        if (!Objects.isNull(address)) {
            queryWrapper.like(House::getAddress, address);
        }
        Page<House> housePage = new Page<>(pageNum, pageSize);
        page(housePage, queryWrapper);
        PageVo<House> housePageVo = new PageVo<>();
        housePageVo.setTotal(housePage.getTotal());
        housePageVo.setPageTotal(housePage.getPages());
        housePageVo.setResult(housePage.getRecords());

        return ResponseResult.okResult(housePageVo);
    }

    @Override
    @Transactional
    public ResponseResult insertHouseDetail(HouseDTO houseDTO) {

        Snowflake snowflake = IdUtil.createSnowflake(1, 1);
        Long id = snowflake.nextId();

        House house = BeanCopyUtils.copyBean(houseDTO, House.class);
        house.setId(id);
        save(house);

        Arrays.stream(houseDTO.getProList()).forEach(propertyId -> {
            HouseProperty property = new HouseProperty();
            property.setPropertyId(Integer.valueOf(propertyId))
                    .setHouseId(id);
            housePropertyService.save(property);
        });

        //HouseImg houseImg = new HouseImg();
        //String[] imgList = houseDTO.getImgList();
        //houseImg.setHouseId(id);
        //houseImgService.save(houseImg);

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult filter(String address, Integer price, Integer stars, String title) {
        LambdaQueryWrapper<House> queryWrapper = new LambdaQueryWrapper<>();
        if (!Objects.isNull(address)) {
            queryWrapper.like(House::getAddress, address);
        }
        if (!Objects.isNull(title)) {
            queryWrapper.like(House::getTitle, title);
        }
        if (!Objects.isNull(price)) {
            // 价格200以上
            if (price == 1) {
                queryWrapper.gt(House::getPrice, 200);
            }
            // 价格100到200 >100 <=200
            else if (price == 2) {
                queryWrapper.gt(House::getPrice, 100)
                        .le(House::getPrice, 200);
            }
            // 100以内
            else {
                queryWrapper.le(House::getPrice, 200);
            }
        }
        if (!Objects.isNull(stars)) {
            // >=4.8
            if (stars == 1) {
                queryWrapper.ge(House::getStars, 4.8);
            }
            // >=4.5
            else if (stars == 2) {
                queryWrapper.ge(House::getStars, 4.5);

            }
            // >=4.2
            else {
                queryWrapper.ge(House::getStars, 4.2);
            }
        }
        List<House> houseList = list(queryWrapper);
        return ResponseResult.okResult(houseList);
    }

}

